home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / lpc / RCS / cmds.c,v < prev    next >
Encoding:
Text File  |  1989-01-23  |  20.3 KB  |  1,034 lines

  1. head     1.3;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.3
  10. date     89.01.23.15.11.10;  author rab;  state Exp;
  11. branches ;
  12. next     1.2;
  13.  
  14. 1.2
  15. date     89.01.11.08.56.53;  author rab;  state Exp;
  16. branches ;
  17. next     1.1;
  18.  
  19. 1.1
  20. date     88.11.23.10.34.50;  author rab;  state Exp;
  21. branches ;
  22. next     ;
  23.  
  24.  
  25. desc
  26. @@
  27.  
  28.  
  29. 1.3
  30. log
  31. @renamed `select' and `abort' to not conflict with library routines.
  32. @
  33. text
  34. @/*
  35.  * Copyright (c) 1983 Regents of the University of California.
  36.  * All rights reserved.
  37.  *
  38.  * Redistribution and use in source and binary forms are permitted
  39.  * provided that this notice is preserved and that due credit is given
  40.  * to the University of California at Berkeley. The name of the University
  41.  * may not be used to endorse or promote products derived from this
  42.  * software without specific prior written permission. This software
  43.  * is provided ``as is'' without express or implied warranty.
  44.  */
  45.  
  46. #ifndef lint
  47. static char sccsid[] = "@@(#)cmds.c    5.3 (Berkeley) 5/5/88";
  48. #endif /* not lint */
  49.  
  50. /*
  51.  * lpc -- line printer control program -- commands:
  52.  */
  53.  
  54. #include "lp.h"
  55. #include <sys/time.h>
  56.  
  57. /*
  58.  * kill an existing daemon and disable printing.
  59.  */
  60. Abort(argc, argv)
  61.     char *argv[];
  62. {
  63.     register int c, status;
  64.     register char *cp1, *cp2;
  65.     char prbuf[100];
  66.  
  67.     if (argc == 1) {
  68.         printf("Usage: abort {all | printer ...}\n");
  69.         return;
  70.     }
  71.     if (argc == 2 && !strcmp(argv[1], "all")) {
  72.         printer = prbuf;
  73.         while (getprent(line) > 0) {
  74.             cp1 = prbuf;
  75.             cp2 = line;
  76.             while ((c = *cp2++) && c != '|' && c != ':')
  77.                 *cp1++ = c;
  78.             *cp1 = '\0';
  79.             abortpr(1);
  80.         }
  81.         return;
  82.     }
  83.     while (--argc) {
  84.         printer = *++argv;
  85.         if ((status = pgetent(line, printer)) < 0) {
  86.             printf("cannot open printer description file\n");
  87.             continue;
  88.         } else if (status == 0) {
  89.             printf("unknown printer %s\n", printer);
  90.             continue;
  91.         }
  92.         abortpr(1);
  93.     }
  94. }
  95.  
  96. abortpr(dis)
  97. {
  98.     register FILE *fp;
  99.     struct stat stbuf;
  100.     int pid, fd;
  101.  
  102.     bp = pbuf;
  103.     if ((SD = pgetstr("sd", &bp)) == NULL)
  104.         SD = DEFSPOOL;
  105.     if ((LO = pgetstr("lo", &bp)) == NULL)
  106.         LO = DEFLOCK;
  107.     (void) sprintf(line, "%s/%s", SD, LO);
  108.     printf("%s:\n", printer);
  109.  
  110.     /*
  111.      * Turn on the owner execute bit of the lock file to disable printing.
  112.      */
  113.     if (dis) {
  114.         if (stat(line, &stbuf) >= 0) {
  115.             if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
  116.                 printf("\tcannot disable printing\n");
  117.             else
  118.                 printf("\tprinting disabled\n");
  119.         } else if (errno == ENOENT) {
  120.             if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
  121.                 printf("\tcannot create lock file\n");
  122.             else {
  123.                 (void) close(fd);
  124.                 printf("\tprinting disabled\n");
  125.                 printf("\tno daemon to abort\n");
  126.             }
  127.             return;
  128.         } else {
  129.             printf("\tcannot stat lock file\n");
  130.             return;
  131.         }
  132.     }
  133.     /*
  134.      * Kill the current daemon to stop printing now.
  135.      */
  136.     if ((fp = fopen(line, "r")) == NULL) {
  137.         printf("\tcannot open lock file\n");
  138.         return;
  139.     }
  140.     if (!getline(fp) || flock(fileno(fp), LOCK_SH|LOCK_NB) == 0) {
  141.         (void) fclose(fp);    /* unlocks as well */
  142.         printf("\tno daemon to abort\n");
  143.         return;
  144.     }
  145.     (void) fclose(fp);
  146. #ifdef sprite
  147.     /*
  148.      * sprite process id's are always printed in hex
  149.      */
  150.     if (kill(pid = atoi(line), SIGTERM) < 0)
  151.         printf("\tWarning: daemon (pid 0x%x) not killed\n", pid);
  152.     else
  153.         printf("\tdaemon (pid 0x%x) killed\n", pid);
  154. #else
  155.     if (kill(pid = atoi(line), SIGTERM) < 0)
  156.         printf("\tWarning: daemon (pid %d) not killed\n", pid);
  157.     else
  158.         printf("\tdaemon (pid %d) killed\n", pid);
  159. #endif
  160. }
  161.  
  162. /*
  163.  * Remove all spool files and temporaries from the spooling area.
  164.  */
  165. clean(argc, argv)
  166.     char *argv[];
  167. {
  168.     register int c, status;
  169.     register char *cp1, *cp2;
  170.     char prbuf[100];
  171.  
  172.     if (argc == 1) {
  173.         printf("Usage: clean {all | printer ...}\n");
  174.         return;
  175.     }
  176.     if (argc == 2 && !strcmp(argv[1], "all")) {
  177.         printer = prbuf;
  178.         while (getprent(line) > 0) {
  179.             cp1 = prbuf;
  180.             cp2 = line;
  181.             while ((c = *cp2++) && c != '|' && c != ':')
  182.                 *cp1++ = c;
  183.             *cp1 = '\0';
  184.             cleanpr();
  185.         }
  186.         return;
  187.     }
  188.     while (--argc) {
  189.         printer = *++argv;
  190.         if ((status = pgetent(line, printer)) < 0) {
  191.             printf("cannot open printer description file\n");
  192.             continue;
  193.         } else if (status == 0) {
  194.             printf("unknown printer %s\n", printer);
  195.             continue;
  196.         }
  197.         cleanpr();
  198.     }
  199. }
  200.  
  201. fileSelect(d)
  202. struct direct *d;
  203. {
  204.     int c = d->d_name[0];
  205.  
  206.     if ((c == 't' || c == 'c' || c == 'd') && d->d_name[1] == 'f')
  207.         return(1);
  208.     return(0);
  209. }
  210.  
  211. /*
  212.  * Comparison routine for scandir. Sort by job number and machine, then
  213.  * by `cf', `tf', or `df', then by the sequence letter A-Z, a-z.
  214.  */
  215. sortq(d1, d2)
  216. struct direct **d1, **d2;
  217. {
  218.     int c1, c2;
  219.  
  220.     if (c1 = strcmp((*d1)->d_name + 3, (*d2)->d_name + 3))
  221.         return(c1);
  222.     c1 = (*d1)->d_name[0];
  223.     c2 = (*d2)->d_name[0];
  224.     if (c1 == c2)
  225.         return((*d1)->d_name[2] - (*d2)->d_name[2]);
  226.     if (c1 == 'c')
  227.         return(-1);
  228.     if (c1 == 'd' || c2 == 'c')
  229.         return(1);
  230.     return(-1);
  231. }
  232.  
  233. /*
  234.  * Remove incomplete jobs from spooling area.
  235.  */
  236. cleanpr()
  237. {
  238.     register int i, n;
  239.     register char *cp, *cp1, *lp;
  240.     struct direct **queue;
  241.     int nitems;
  242.  
  243.     bp = pbuf;
  244.     if ((SD = pgetstr("sd", &bp)) == NULL)
  245.         SD = DEFSPOOL;
  246.     printf("%s:\n", printer);
  247.  
  248.     for (lp = line, cp = SD; *lp++ = *cp++; )
  249.         ;
  250.     lp[-1] = '/';
  251.  
  252.     nitems = scandir(SD, &queue, fileSelect, sortq);
  253.     if (nitems < 0) {
  254.         printf("\tcannot examine spool directory\n");
  255.         return;
  256.     }
  257.     if (nitems == 0)
  258.         return;
  259.     i = 0;
  260.     do {
  261.         cp = queue[i]->d_name;
  262.         if (*cp == 'c') {
  263.             n = 0;
  264.             while (i + 1 < nitems) {
  265.                 cp1 = queue[i + 1]->d_name;
  266.                 if (*cp1 != 'd' || strcmp(cp + 3, cp1 + 3))
  267.                     break;
  268.                 i++;
  269.                 n++;
  270.             }
  271.             if (n == 0) {
  272.                 strcpy(lp, cp);
  273.                 unlinkf(line);
  274.             }
  275.         } else {
  276.             /*
  277.              * Must be a df with no cf (otherwise, it would have
  278.              * been skipped above) or a tf file (which can always
  279.              * be removed).
  280.              */
  281.             strcpy(lp, cp);
  282.             unlinkf(line);
  283.         }
  284.          } while (++i < nitems);
  285. }
  286.  
  287. unlinkf(name)
  288.     char    *name;
  289. {
  290.     if (unlink(name) < 0)
  291.         printf("\tcannot remove %s\n", name);
  292.     else
  293.         printf("\tremoved %s\n", name);
  294. }
  295.  
  296. /*
  297.  * Enable queuing to the printer (allow lpr's).
  298.  */
  299. enable(argc, argv)
  300.     char *argv[];
  301. {
  302.     register int c, status;
  303.     register char *cp1, *cp2;
  304.     char prbuf[100];
  305.  
  306.     if (argc == 1) {
  307.         printf("Usage: enable {all | printer ...}\n");
  308.         return;
  309.     }
  310.     if (argc == 2 && !strcmp(argv[1], "all")) {
  311.         printer = prbuf;
  312.         while (getprent(line) > 0) {
  313.             cp1 = prbuf;
  314.             cp2 = line;
  315.             while ((c = *cp2++) && c != '|' && c != ':')
  316.                 *cp1++ = c;
  317.             *cp1 = '\0';
  318.             enablepr();
  319.         }
  320.         return;
  321.     }
  322.     while (--argc) {
  323.         printer = *++argv;
  324.         if ((status = pgetent(line, printer)) < 0) {
  325.             printf("cannot open printer description file\n");
  326.             continue;
  327.         } else if (status == 0) {
  328.             printf("unknown printer %s\n", printer);
  329.             continue;
  330.         }
  331.         enablepr();
  332.     }
  333. }
  334.  
  335. enablepr()
  336. {
  337.     struct stat stbuf;
  338.  
  339.     bp = pbuf;
  340.     if ((SD = pgetstr("sd", &bp)) == NULL)
  341.         SD = DEFSPOOL;
  342.     if ((LO = pgetstr("lo", &bp)) == NULL)
  343.         LO = DEFLOCK;
  344.     (void) sprintf(line, "%s/%s", SD, LO);
  345.     printf("%s:\n", printer);
  346.  
  347.     /*
  348.      * Turn off the group execute bit of the lock file to enable queuing.
  349.      */
  350.     if (stat(line, &stbuf) >= 0) {
  351.         if (chmod(line, stbuf.st_mode & 0767) < 0)
  352.             printf("\tcannot enable queuing\n");
  353.         else
  354.             printf("\tqueuing enabled\n");
  355.     }
  356. }
  357.  
  358. /*
  359.  * Disable queuing.
  360.  */
  361. disable(argc, argv)
  362.     char *argv[];
  363. {
  364.     register int c, status;
  365.     register char *cp1, *cp2;
  366.     char prbuf[100];
  367.  
  368.     if (argc == 1) {
  369.         printf("Usage: disable {all | printer ...}\n");
  370.         return;
  371.     }
  372.     if (argc == 2 && !strcmp(argv[1], "all")) {
  373.         printer = prbuf;
  374.         while (getprent(line) > 0) {
  375.             cp1 = prbuf;
  376.             cp2 = line;
  377.             while ((c = *cp2++) && c != '|' && c != ':')
  378.                 *cp1++ = c;
  379.             *cp1 = '\0';
  380.             disablepr();
  381.         }
  382.         return;
  383.     }
  384.     while (--argc) {
  385.         printer = *++argv;
  386.         if ((status = pgetent(line, printer)) < 0) {
  387.             printf("cannot open printer description file\n");
  388.             continue;
  389.         } else if (status == 0) {
  390.             printf("unknown printer %s\n", printer);
  391.             continue;
  392.         }
  393.         disablepr();
  394.     }
  395. }
  396.  
  397. disablepr()
  398. {
  399.     register int fd;
  400.     struct stat stbuf;
  401.  
  402.     bp = pbuf;
  403.     if ((SD = pgetstr("sd", &bp)) == NULL)
  404.         SD = DEFSPOOL;
  405.     if ((LO = pgetstr("lo", &bp)) == NULL)
  406.         LO = DEFLOCK;
  407.     (void) sprintf(line, "%s/%s", SD, LO);
  408.     printf("%s:\n", printer);
  409.     /*
  410.      * Turn on the group execute bit of the lock file to disable queuing.
  411.      */
  412.     if (stat(line, &stbuf) >= 0) {
  413.         if (chmod(line, (stbuf.st_mode & 0777) | 010) < 0)
  414.             printf("\tcannot disable queuing\n");
  415.         else
  416.             printf("\tqueuing disabled\n");
  417.     } else if (errno == ENOENT) {
  418.         if ((fd = open(line, O_WRONLY|O_CREAT, 0670)) < 0)
  419.             printf("\tcannot create lock file\n");
  420.         else {
  421.             (void) close(fd);
  422.             printf("\tqueuing disabled\n");
  423.         }
  424.         return;
  425.     } else
  426.         printf("\tcannot stat lock file\n");
  427. }
  428.  
  429. /*
  430.  * Disable queuing and printing and put a message into the status file
  431.  * (reason for being down).
  432.  */
  433. down(argc, argv)
  434.     char *argv[];
  435. {
  436.     register int c, status;
  437.     register char *cp1, *cp2;
  438.     char prbuf[100];
  439.  
  440.     if (argc == 1) {
  441.         printf("Usage: down {all | printer} [message ...]\n");
  442.         return;
  443.     }
  444.     if (!strcmp(argv[1], "all")) {
  445.         printer = prbuf;
  446.         while (getprent(line) > 0) {
  447.             cp1 = prbuf;
  448.             cp2 = line;
  449.             while ((c = *cp2++) && c != '|' && c != ':')
  450.                 *cp1++ = c;
  451.             *cp1 = '\0';
  452.             putmsg(argc - 2, argv + 2);
  453.         }
  454.         return;
  455.     }
  456.     printer = argv[1];
  457.     if ((status = pgetent(line, printer)) < 0) {
  458.         printf("cannot open printer description file\n");
  459.         return;
  460.     } else if (status == 0) {
  461.         printf("unknown printer %s\n", printer);
  462.         return;
  463.     }
  464.     putmsg(argc - 2, argv + 2);
  465. }
  466.  
  467. putmsg(argc, argv)
  468.     char **argv;
  469. {
  470.     register int fd;
  471.     register char *cp1, *cp2;
  472.     char buf[1024];
  473.     struct stat stbuf;
  474.  
  475.     bp = pbuf;
  476.     if ((SD = pgetstr("sd", &bp)) == NULL)
  477.         SD = DEFSPOOL;
  478.     if ((LO = pgetstr("lo", &bp)) == NULL)
  479.         LO = DEFLOCK;
  480.     if ((ST = pgetstr("st", &bp)) == NULL)
  481.         ST = DEFSTAT;
  482.     printf("%s:\n", printer);
  483.     /*
  484.      * Turn on the group execute bit of the lock file to disable queuing and
  485.      * turn on the owner execute bit of the lock file to disable printing.
  486.      */
  487.     (void) sprintf(line, "%s/%s", SD, LO);
  488.     if (stat(line, &stbuf) >= 0) {
  489.         if (chmod(line, (stbuf.st_mode & 0777) | 0110) < 0)
  490.             printf("\tcannot disable queuing\n");
  491.         else
  492.             printf("\tprinter and queuing disabled\n");
  493.     } else if (errno == ENOENT) {
  494.         if ((fd = open(line, O_WRONLY|O_CREAT, 0770)) < 0)
  495.             printf("\tcannot create lock file\n");
  496.         else {
  497.             (void) close(fd);
  498.             printf("\tprinter and queuing disabled\n");
  499.         }
  500.         return;
  501.     } else
  502.         printf("\tcannot stat lock file\n");
  503.     /*
  504.      * Write the message into the status file.
  505.      */
  506.     (void) sprintf(line, "%s/%s", SD, ST);
  507.     fd = open(line, O_WRONLY|O_CREAT, 0664);
  508.     if (fd < 0 || flock(fd, LOCK_EX) < 0) {
  509.         printf("\tcannot create status file\n");
  510.         return;
  511.     }
  512.     (void) ftruncate(fd, 0);
  513.     if (argc <= 0) {
  514.         (void) write(fd, "\n", 1);
  515.         (void) close(fd);
  516.         return;
  517.     }
  518.     cp1 = buf;
  519.     while (--argc >= 0) {
  520.         cp2 = *argv++;
  521.         while (*cp1++ = *cp2++)
  522.             ;
  523.         cp1[-1] = ' ';
  524.     }
  525.     cp1[-1] = '\n';
  526.     *cp1 = '\0';
  527.     (void) write(fd, buf, strlen(buf));
  528.     (void) close(fd);
  529. }
  530.  
  531. /*
  532.  * Exit lpc
  533.  */
  534. quit(argc, argv)
  535.     char *argv[];
  536. {
  537.     exit(0);
  538. }
  539.  
  540. /*
  541.  * Kill and restart the daemon.
  542.  */
  543. restart(argc, argv)
  544.     char *argv[];
  545. {
  546.     register int c, status;
  547.     register char *cp1, *cp2;
  548.     char prbuf[100];
  549.  
  550.     if (argc == 1) {
  551.         printf("Usage: restart {all | printer ...}\n");
  552.         return;
  553.     }
  554.     if (argc == 2 && !strcmp(argv[1], "all")) {
  555.         printer = prbuf;
  556.         while (getprent(line) > 0) {
  557.             cp1 = prbuf;
  558.             cp2 = line;
  559.             while ((c = *cp2++) && c != '|' && c != ':')
  560.                 *cp1++ = c;
  561.             *cp1 = '\0';
  562.             abortpr(0);
  563.             startpr(0);
  564.         }
  565.         return;
  566.     }
  567.     while (--argc) {
  568.         printer = *++argv;
  569.         if ((status = pgetent(line, printer)) < 0) {
  570.             printf("cannot open printer description file\n");
  571.             continue;
  572.         } else if (status == 0) {
  573.             printf("unknown printer %s\n", printer);
  574.             continue;
  575.         }
  576.         abortpr(0);
  577.         startpr(0);
  578.     }
  579. }
  580.  
  581. /*
  582.  * Enable printing on the specified printer and startup the daemon.
  583.  */
  584. start(argc, argv)
  585.     char *argv[];
  586. {
  587.     register int c, status;
  588.     register char *cp1, *cp2;
  589.     char prbuf[100];
  590.  
  591.     if (argc == 1) {
  592.         printf("Usage: start {all | printer ...}\n");
  593.         return;
  594.     }
  595.     if (argc == 2 && !strcmp(argv[1], "all")) {
  596.         printer = prbuf;
  597.         while (getprent(line) > 0) {
  598.             cp1 = prbuf;
  599.             cp2 = line;
  600.             while ((c = *cp2++) && c != '|' && c != ':')
  601.                 *cp1++ = c;
  602.             *cp1 = '\0';
  603.             startpr(1);
  604.         }
  605.         return;
  606.     }
  607.     while (--argc) {
  608.         printer = *++argv;
  609.         if ((status = pgetent(line, printer)) < 0) {
  610.             printf("cannot open printer description file\n");
  611.             continue;
  612.         } else if (status == 0) {
  613.             printf("unknown printer %s\n", printer);
  614.             continue;
  615.         }
  616.         startpr(1);
  617.     }
  618. }
  619.  
  620. startpr(enable)
  621. {
  622.     struct stat stbuf;
  623.  
  624.     bp = pbuf;
  625.     if ((SD = pgetstr("sd", &bp)) == NULL)
  626.         SD = DEFSPOOL;
  627.     if ((LO = pgetstr("lo", &bp)) == NULL)
  628.         LO = DEFLOCK;
  629.     (void) sprintf(line, "%s/%s", SD, LO);
  630.     printf("%s:\n", printer);
  631.  
  632.     /*
  633.      * Turn off the owner execute bit of the lock file to enable printing.
  634.      */
  635.     if (enable && stat(line, &stbuf) >= 0) {
  636.         if (chmod(line, stbuf.st_mode & (enable==2 ? 0666 : 0677)) < 0)
  637.             printf("\tcannot enable printing\n");
  638.         else
  639.             printf("\tprinting enabled\n");
  640.     }
  641.     if (!startdaemon(printer))
  642.         printf("\tcouldn't start daemon\n");
  643.     else
  644.         printf("\tdaemon started\n");
  645. }
  646.  
  647. /*
  648.  * Print the status of each queue listed or all the queues.
  649.  */
  650. status(argc, argv)
  651.     char *argv[];
  652. {
  653.     register int c, status;
  654.     register char *cp1, *cp2;
  655.     char prbuf[100];
  656.  
  657.     if (argc == 1) {
  658.         printer = prbuf;
  659.         while (getprent(line) > 0) {
  660.             cp1 = prbuf;
  661.             cp2 = line;
  662.             while ((c = *cp2++) && c != '|' && c != ':')
  663.                 *cp1++ = c;
  664.             *cp1 = '\0';
  665.             prstat();
  666.         }
  667.         return;
  668.     }
  669.     while (--argc) {
  670.         printer = *++argv;
  671.         if ((status = pgetent(line, printer)) < 0) {
  672.             printf("cannot open printer description file\n");
  673.             continue;
  674.         } else if (status == 0) {
  675.             printf("unknown printer %s\n", printer);
  676.             continue;
  677.         }
  678.         prstat();
  679.     }
  680. }
  681.  
  682. /*
  683.  * Print the status of the printer queue.
  684.  */
  685. prstat()
  686. {
  687.     struct stat stbuf;
  688.     register int fd, i;
  689.     register struct direct *dp;
  690.     DIR *dirp;
  691.  
  692.     bp = pbuf;
  693.     if ((SD = pgetstr("sd", &bp)) == NULL)
  694.         SD = DEFSPOOL;
  695.     if ((LO = pgetstr("lo", &bp)) == NULL)
  696.         LO = DEFLOCK;
  697.     if ((ST = pgetstr("st", &bp)) == NULL)
  698.         ST = DEFSTAT;
  699.     printf("%s:\n", printer);
  700.     (void) sprintf(line, "%s/%s", SD, LO);
  701.     if (stat(line, &stbuf) >= 0) {
  702.         printf("\tqueuing is %s\n",
  703.             (stbuf.st_mode & 010) ? "disabled" : "enabled");
  704.         printf("\tprinting is %s\n",
  705.             (stbuf.st_mode & 0100) ? "disabled" : "enabled");
  706.     } else {
  707.         printf("\tqueuing is enabled\n");
  708.         printf("\tprinting is enabled\n");
  709.     }
  710.     if ((dirp = opendir(SD)) == NULL) {
  711.         printf("\tcannot examine spool directory\n");
  712.         return;
  713.     }
  714.     i = 0;
  715.     while ((dp = readdir(dirp)) != NULL) {
  716.         if (*dp->d_name == 'c' && dp->d_name[1] == 'f')
  717.             i++;
  718.     }
  719.     closedir(dirp);
  720.     if (i == 0)
  721.         printf("\tno entries\n");
  722.     else if (i == 1)
  723.         printf("\t1 entry in spool area\n");
  724.     else
  725.         printf("\t%d entries in spool area\n", i);
  726.     fd = open(line, O_RDONLY);
  727.     if (fd < 0 || flock(fd, LOCK_SH|LOCK_NB) == 0) {
  728.         (void) close(fd);    /* unlocks as well */
  729.         printf("\tno daemon present\n");
  730.         return;
  731.     }
  732.     (void) close(fd);
  733.     putchar('\t');
  734.     (void) sprintf(line, "%s/%s", SD, ST);
  735.     fd = open(line, O_RDONLY);
  736.     if (fd >= 0) {
  737.         (void) flock(fd, LOCK_SH);
  738.         while ((i = read(fd, line, sizeof(line))) > 0)
  739.             (void) fwrite(line, 1, i, stdout);
  740.         (void) close(fd);    /* unlocks as well */
  741.     }
  742. }
  743.  
  744. /*
  745.  * Stop the specified daemon after completing the current job and disable
  746.  * printing.
  747.  */
  748. stop(argc, argv)
  749.     char *argv[];
  750. {
  751.     register int c, status;
  752.     register char *cp1, *cp2;
  753.     char prbuf[100];
  754.  
  755.     if (argc == 1) {
  756.         printf("Usage: stop {all | printer ...}\n");
  757.         return;
  758.     }
  759.     if (argc == 2 && !strcmp(argv[1], "all")) {
  760.         printer = prbuf;
  761.         while (getprent(line) > 0) {
  762.             cp1 = prbuf;
  763.             cp2 = line;
  764.             while ((c = *cp2++) && c != '|' && c != ':')
  765.                 *cp1++ = c;
  766.             *cp1 = '\0';
  767.             stoppr();
  768.         }
  769.         return;
  770.     }
  771.     while (--argc) {
  772.         printer = *++argv;
  773.         if ((status = pgetent(line, printer)) < 0) {
  774.             printf("cannot open printer description file\n");
  775.             continue;
  776.         } else if (status == 0) {
  777.             printf("unknown printer %s\n", printer);
  778.             continue;
  779.         }
  780.         stoppr();
  781.     }
  782. }
  783.  
  784. stoppr()
  785. {
  786.     register int fd;
  787.     struct stat stbuf;
  788.  
  789.     bp = pbuf;
  790.     if ((SD = pgetstr("sd", &bp)) == NULL)
  791.         SD = DEFSPOOL;
  792.     if ((LO = pgetstr("lo", &bp)) == NULL)
  793.         LO = DEFLOCK;
  794.     (void) sprintf(line, "%s/%s", SD, LO);
  795.     printf("%s:\n", printer);
  796.  
  797.     /*
  798.      * Turn on the owner execute bit of the lock file to disable printing.
  799.      */
  800.     if (stat(line, &stbuf) >= 0) {
  801.         if (chmod(line, (stbuf.st_mode & 0777) | 0100) < 0)
  802.             printf("\tcannot disable printing\n");
  803.         else
  804.             printf("\tprinting disabled\n");
  805.     } else if (errno == ENOENT) {
  806.         if ((fd = open(line, O_WRONLY|O_CREAT, 0760)) < 0)
  807.             printf("\tcannot create lock file\n");
  808.         else {
  809.             (void) close(fd);
  810.             printf("\tprinting disabled\n");
  811.         }
  812.     } else
  813.         printf("\tcannot stat lock file\n");
  814. }
  815.  
  816. struct    queue **queue;
  817. int    nitems;
  818. time_t    mtime;
  819.  
  820. /*
  821.  * Put the specified jobs at the top of printer queue.
  822.  */
  823. topq(argc, argv)
  824.     char *argv[];
  825. {
  826.     register int n, i;
  827.     struct stat stbuf;
  828.     register char *cfname;
  829.     int status, changed;
  830.  
  831.     if (argc < 3) {
  832.         printf("Usage: topq printer [jobnum ...] [user ...]\n");
  833.         return;
  834.     }
  835.  
  836.     --argc;
  837.     printer = *++argv;
  838.     status = pgetent(line, printer);
  839.     if (status < 0) {
  840.         printf("cannot open printer description file\n");
  841.         return;
  842.     } else if (status == 0) {
  843.         printf("%s: unknown printer\n", printer);
  844.         return;
  845.     }
  846.     bp = pbuf;
  847.     if ((SD = pgetstr("sd", &bp)) == NULL)
  848.         SD = DEFSPOOL;
  849.     if ((LO = pgetstr("lo", &bp)) == NULL)
  850.         LO = DEFLOCK;
  851.     printf("%s:\n", printer);
  852.  
  853.     if (chdir(SD) < 0) {
  854.         printf("\tcannot chdir to %s\n", SD);
  855.         return;
  856.     }
  857.     nitems = getq(&queue);
  858.     if (nitems == 0)
  859.         return;
  860.     changed = 0;
  861.     mtime = queue[0]->q_time;
  862.     for (i = argc; --i; ) {
  863.         if (doarg(argv[i]) == 0) {
  864.             printf("\tjob %s is not in the queue\n", argv[i]);
  865.             continue;
  866.         } else
  867.             changed++;
  868.     }
  869.     for (i = 0; i < nitems; i++)
  870.         free(queue[i]);
  871.     free(queue);
  872.     if (!changed) {
  873.         printf("\tqueue order unchanged\n");
  874.         return;
  875.     }
  876.     /*
  877.      * Turn on the public execute bit of the lock file to
  878.      * get lpd to rebuild the queue after the current job.
  879.      */
  880.     if (changed && stat(LO, &stbuf) >= 0)
  881.         (void) chmod(LO, (stbuf.st_mode & 0777) | 01);
  882.  
  883. /*
  884.  * Reposition the job by changing the modification time of
  885.  * the control file.
  886.  */
  887. touch(q)
  888.     struct queue *q;
  889. {
  890.     struct timeval tvp[2];
  891.  
  892.     tvp[0].tv_sec = tvp[1].tv_sec = --mtime;
  893.     tvp[0].tv_usec = tvp[1].tv_usec = 0;
  894.     return(utimes(q->q_name, tvp));
  895. }
  896.  
  897. /*
  898.  * Checks if specified job name is in the printer's queue.
  899.  * Returns:  negative (-1) if argument name is not in the queue.
  900.  */
  901. doarg(job)
  902.     char *job;
  903. {
  904.     register struct queue **qq;
  905.     register int jobnum, n;
  906.     register char *cp, *machine;
  907.     int cnt = 0;
  908.     FILE *fp;
  909.  
  910.     /*
  911.      * Look for a job item consisting of system name, colon, number 
  912.      * (example: ucbarpa:114)  
  913.      */
  914.     if ((cp = index(job, ':')) != NULL) {
  915.         machine = job;
  916.         *cp++ = '\0';
  917.         job = cp;
  918.     } else
  919.         machine = NULL;
  920.  
  921.     /*
  922.      * Check for job specified by number (example: 112 or 235ucbarpa).
  923.      */
  924.     if (isdigit(*job)) {
  925.         jobnum = 0;
  926.         do
  927.             jobnum = jobnum * 10 + (*job++ - '0');
  928.         while (isdigit(*job));
  929.         for (qq = queue + nitems; --qq >= queue; ) {
  930.             n = 0;
  931.             for (cp = (*qq)->q_name+3; isdigit(*cp); )
  932.                 n = n * 10 + (*cp++ - '0');
  933.             if (jobnum != n)
  934.                 continue;
  935.             if (*job && strcmp(job, cp) != 0)
  936.                 continue;
  937.             if (machine != NULL && strcmp(machine, cp) != 0)
  938.                 continue;
  939.             if (touch(*qq) == 0) {
  940.                 printf("\tmoved %s\n", (*qq)->q_name);
  941.                 cnt++;
  942.             }
  943.         }
  944.         return(cnt);
  945.     }
  946.     /*
  947.      * Process item consisting of owner's name (example: henry).
  948.      */
  949.     for (qq = queue + nitems; --qq >= queue; ) {
  950.         if ((fp = fopen((*qq)->q_name, "r")) == NULL)
  951.             continue;
  952.         while (getline(fp) > 0)
  953.             if (line[0] == 'P')
  954.                 break;
  955.         (void) fclose(fp);
  956.         if (line[0] != 'P' || strcmp(job, line+1) != 0)
  957.             continue;
  958.         if (touch(*qq) == 0) {
  959.             printf("\tmoved %s\n", (*qq)->q_name);
  960.             cnt++;
  961.         }
  962.     }
  963.     return(cnt);
  964. }
  965.  
  966. /*
  967.  * Enable everything and start printer (undo `down').
  968.  */
  969. up(argc, argv)
  970.     char *argv[];
  971. {
  972.     register int c, status;
  973.     register char *cp1, *cp2;
  974.     char prbuf[100];
  975.  
  976.     if (argc == 1) {
  977.         printf("Usage: up {all | printer ...}\n");
  978.         return;
  979.     }
  980.     if (argc == 2 && !strcmp(argv[1], "all")) {
  981.         printer = prbuf;
  982.         while (getprent(line) > 0) {
  983.             cp1 = prbuf;
  984.             cp2 = line;
  985.             while ((c = *cp2++) && c != '|' && c != ':')
  986.                 *cp1++ = c;
  987.             *cp1 = '\0';
  988.             startpr(2);
  989.         }
  990.         return;
  991.     }
  992.     while (--argc) {
  993.         printer = *++argv;
  994.         if ((status = pgetent(line, printer)) < 0) {
  995.             printf("cannot open printer description file\n");
  996.             continue;
  997.         } else if (status == 0) {
  998.             printf("unknown printer %s\n", printer);
  999.             continue;
  1000.         }
  1001.         startpr(2);
  1002.     }
  1003. }
  1004. @
  1005.  
  1006.  
  1007. 1.2
  1008. log
  1009. @*** empty log message ***
  1010. @
  1011. text
  1012. @d27 1
  1013. a27 1
  1014. abort(argc, argv)
  1015. d168 1
  1016. a168 1
  1017. select(d)
  1018. d219 1
  1019. a219 1
  1020.     nitems = scandir(SD, &queue, select, sortq);
  1021. @
  1022.  
  1023.  
  1024. 1.1
  1025. log
  1026. @Initial revision
  1027. @
  1028. text
  1029. @d113 4
  1030. d118 5
  1031. d126 1
  1032. @
  1033.